/*
  I2C GPS, Data Logger, & GPIO
  
  This Sketch implements a Ublox GPS interface, DataLogger, and GPIO
  as an I2C Slave device.  GPIO includes digital and analog inputs and outputs.
  
  This is part of the OSFC Open Source Flight Controller Project.
  
  I2C Interface Summary:
  Slave I2C Address is 0x48 : I2C_SLAVE
  
  General Command Format:
  I2C_Address(W) : Command Byte : Optional Bytes
  
  Command   Action                Optional Bytes
  -------   ------------------    --------------------
  0x00      Write Bytes to Log    Bytes to Write - Note: File must be Open First

  0x02      Open File             None- Default Name is LOGxxx.TXT

  0x04      Close File            None

  0x08      Set Log File Name     File Name for next Open command
                                  Overwrites any previous or default file name
                                  Must be "8.3" format
                                  
  0x0A      Reset Default File    2 byte int - Little Endian - New Default Number
  
  0x0C      Set Min AutoLog Time  2 byte int - Little Endian - milliseconds
                                  
  0x0E      GPS Autolog           One Byte: '0' = OFF, !=0 = ON
                                  AutoLog OFF is default
                                  
  0x0F      Set Platform Model    One Byte - See u-blox documentation
  ==============================================================================
  General Read Format:
  I2C_Address(W) : Read Addr Byte : I2C_Address(R) : Read n Bytes
  
  Read Addr  Bytes to Read     N Bytes  Values(Bytes) (Note: Little-endian)
  ---------  -----------------  -----   ------------------------------------
  0x80       Read GPS Position   12     Latitude (4), Longitude(4), Altitude(4)
                                        Lat, Lon in degrees x 10^6, Alt in cm AMSL

  0x8C       Read GPS Velocity   12     Course(2), Speed(2), cos(course)(2), sin(course)(2)
                                        V_north(2), V_east(2)
                                        Course in degrees x 10, cos, sin as Fix_16_14
                                        Velocities in cm/s (m/s x 100)

  0x98       Read GPS age         4     Age of GPS values, milliseconds

  0x9C       Read GPS status      1     GPS Status:
                                        7: (MSB) GPS fix within timeout (5 s)
                                        6: Char recieved from GPS within timeout (1 s)
                                        5: VTG Message Stopped
                                        4: reserved
                                        3: GSV Message Stopped
                                        2: GSA Message Stopped
                                        1: GLL Message Stopped
                                        0: (LSB) Mode Set Success
                                        
  0x9D       Read Log Status      1     Read Log Status:
                                        7: (MSB) reserved
                                        6: reserved
                                        5: reserved
                                        4: AutoLog On
                                        3: reserved
                                        2: Need File Name
                                        1: File Open
                                        0: (LSB) Have SD
                                        
  TO DO - Add GPIO Functions
                                        
*/
#include <Wire.h>
#include <EEPROM.h>
#include <SD.h>
#include <TinyGPS.h>
#include <UbloxGPS.h>
#include "UbloxI2C.h"
#include "gpsLogCommands.h"


UbloxI2C gps;          // The GPS object

File logFile;          // The SD log file object

String fileName = "";  // File Name container

byte i2cCmd;           // The last received I2C Command
byte logStatus;        // The Logger Status Byte

char comma = ',';

int minLogTime = 1000;  // The minimum time between Autologs

unsigned long lastLog = 0;       // The time of the last Autolog

boolean haveSD = false;          // Init SD success
boolean fileOpen = false;        // Have file open
boolean autoLog = false;         // Do Autolog
boolean timeTagged = false;      // Wrote a time tag to the current file
boolean needFileName = true;     // No File Name Entered since last Open

void setup(void) {
  
  Wire.begin(I2C_SLAVE);         // Join I2C bus as a slave
  Wire.onReceive(receiveHandler);
  Wire.onRequest(requestHandler);
  
  if (SD.begin(10)) {            // Start SD Card Library
    haveSD = true;
    logStatus = 0x05;
  } else {
    haveSD = false;
    logStatus = 0x04;
  }
  needFileName = true;
  
  
  //Serial.begin(9600);
  Serial1.begin(9600);             // Initialize GPS UART
  
  gps.begin(Serial1);              // Initialze GPS
    
  gps.setMode(8);                  // Dynamic Airborne Mode
  
  // Stop un-needed GPS messages
  byte rate[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  gps.setMsgRate(gps.nmeaClass, gps.gllID, rate);
  gps.setMsgRate(gps.nmeaClass, gps.gsaID, rate);
  gps.setMsgRate(gps.nmeaClass, gps.gsvID, rate);
  gps.setMsgRate(gps.nmeaClass, gps.vtgID, rate);
  
}

void loop(void) {
  
  // Process GPS and Autolog data
  if (gps.process()) {
    unsigned long t = millis();
    if (fileOpen && autoLog && ((t - lastLog) > minLogTime)) {
      lastLog = t;
      if(!timeTagged) {
        logFile.println(timeTag());
        timeTagged = true;
      }
      logFile.println(gpsString());
    }
  }
  
  /*
  if (Serial.available()) {
    Serial.read();
    Serial.print("Status = 0x");
    Serial.println(gps.status, HEX);
  }
  */
}


